-------------------------------------------------------------------------------------
-- -*- coding: utf-8 -*-
--
-- @author:   zxf
-- @email:    07291@qq.com
-- @date:     2024/5/31
-- @module:   redis
-- @describe: 药品
-- @version:  v1.0
--

-------------------------------------------------------------------------------------

---@class redis
local redis = {}
local this = redis
--默认redis对象列表
this.redis_obj = {
    ['转金服务'] = { connect_obj = nil, connect_ip = '127.0.0.1', port = 6379, open = true },
    --['转金服务'] = { connect_obj = nil, connect_ip = '192.168.0.111', port = 6379, open = true },
    ['组队服务'] = { connect_obj = nil, connect_ip = '127.0.0.1', port = 6379, open = false },
}
--默认机器ID
this.computer_id = 1
---@type configer
local configer = import("base/configer")
---@type utils
local utils = import("base/utils")
--------------------------------------------------------------------------------
-- 连接redis设置
--
-- @usage
-- local bool = redis_ent.connect_redis()
--------------------------------------------------------------------------------
this.connect_redis = function()
    --设置/读取本机ID和连接IP
    local computer_id = configer.get_profile('本机设置.ini', '*************连接设置*************', '机器ID')
    if computer_id == '' then
        configer.set_profile('本机设置.ini', '*************连接设置*************', '机器ID', '1')
        this.computer_id = 1
    else
        this.computer_id = tonumber(computer_id)
    end
    -- 遍历连接列表
    for k, v in pairs(this.redis_obj) do
        if v.open then
            local connect_ip = configer.get_profile('本机设置.ini', '*************连接设置*************', k .. '连接IP')
            if connect_ip == '' then
                configer.set_profile('本机设置.ini', '*************连接设置*************', k .. '连接IP', v.connect_ip)
            else
                this.redis_obj[k].connect_ip = connect_ip
            end
        end
    end
end



--------------------------------------------------------------------------------------
---[读取]判断指定时间的时间戳是否在今日与下日指定时间段内[默认凌晨4点]
---@param       timestamp   number     时间戳
---@param       hour       number      时
---@return                boolean     是否在该时间段内
-------------------------------------------------------------------------------------
function this.is_in_times(timestamp, hour)
    local need_server = utils.split_string(main_ctx:c_server_name(), '_')[1]
    if need_server == "NAEU" or need_server == "SA" then
        hour = hour or 12
    else
        -- 设置默认时间为凌晨4点
        hour = hour or 4
    end
    -- 将时间戳转换为日期
    local date       = os.date("*t", os.time())
    -- 当前日期的指定时间戳
    local startOfDay = os.time({ year = date.year, month = date.month, day = date.day, hour = hour, min = 0, sec = 0 })
    -- 次日日期的指定时间戳
    local endOfDay   = os.time({ year = date.year, month = date.month, day = date.day + 1, hour = hour, min = 0, sec = 0 })
    -- 如果当日为 指定时之前  则 比较 上一日 hour 到 当日 时
    if utils.get_hour() < hour then
        local lastOfDay = os.time({ year = date.year, month = date.month, day = date.day - 1, hour = hour - 1, min = 59, sec = 59 })
        return timestamp >= lastOfDay and timestamp <= startOfDay
    end
    -- 判断时间戳是否在时间范围内
    return timestamp >= startOfDay and timestamp < endOfDay
end

--------------------------------------------------------------------------------------
-- 该作用主要用于天副本的记录情况，当完成天副本了就在对应的ini文件中进行记录写入，当到达第二天凌晨四点就对其进行更新
-- 在写入时除了写入完成情况，也写入当前的时间戳
-- 在需要读取该记录时，针对记录的时间戳进行判断，如果该时间戳位于今天的凌晨4点到明天凌晨4点之间就返回记录的值
-- 不在该区间即表示已经过期了，不返回相关的记录
---[读取] 获取ini文件中指定键的值，如果读取该值的时间是在写入时间和第二天凌晨4点之前则返回对应的值，否则返回空
---@param       section   string     配置文件中节点名称。
---@param       key       string     配置文件中的键名。
---@return                string     返回的值
--------------------------------------------------------------------------------------
function redis.get_user_profile_today_four(section, key, refresh_time)
    local content = configer.get_user_profile(section, key)
    local parts = utils.split_string(content, ',')
    if #parts == 3 and this.is_in_times(tonumber(parts[1]), refresh_time) then
        return parts[3]
    end
    return ''
end

--------------------------------------------------------------------------------------
---[写入] 将指定用户的配置写入到ini文件中，并将当天日期附加到配置值之前
---@param       section   string     配置文件中节点名称。
---@param       key       string     配置文件中的键名。
---@param       value     string     要写入的字符串。
---@return                boolean    写入操作是否成功。
--------------------------------------------------------------------------------------
function redis.set_user_profile_today_four(section, key, value)
    local content = string.format('%s,%s,%s', os.time(), os.date('%Y-%m-%d-%H'), tostring(value))
    return configer.set_user_profile(section, key, content)
end



--------------------------------------------------------------------------------------
-- 该功能作用于周副本的记录情况，当周副本完成后在对应ini文件中进行记录写入，到了下个星期一凌晨四点进行更新
-- 在取出记录时根据写入的时间戳判断该记录是否要返回
-- 根据写入的时间戳来获取到写入时是一周中的第几天（周日为1，周一为2，以此类推）
-- 以此计算出到达下一个星期一还有几天，特殊判断，如果当前是周一就判断时间点是否超过凌晨四点，超过了就还有七天，没超过就是0天
-- 然后可以得到下个星期一的凌晨四点的时间戳
-- 在取出记录时判断现在时间戳是否超过计算的周一四点时间戳，如果超过就为过期，不返回信息，反之返回信息
---[读取]判断指定时间的时间戳是否超过指定时间戳的下一个周一的凌晨4点
---@param       timestamp   number     时间戳
---@return                boolean     是否在该时间段内
--------------------------------------------------------------------------------------
function redis.is_in_monday_four(timestamp)
    -- 根据传入的timestamp时间戳就算到下一次周一四点的时间戳是多少
    -- 获取传入的timestamp时间戳的是周几
    local record_date = os.date("*t", timestamp)
    --xxmsg("记录时间戳的详情")
    --print_r(record_date)
    local record_wday = record_date.wday

    -- 根据当前是周几计算到下次周一还有几天
    local next_monday = 0
    -- 如果记录的时间戳是周一并且是在凌晨4点之前，则需要加的天数是0
    if record_wday == 2 and record_date.hour < 4 then
        next_monday = 0
    elseif record_wday == 1 then
        next_monday = 1
    else
        next_monday = 9 - record_wday
    end
    --xxmsg("现在时间的时间戳详情")
    --print_r(os.date("*t",os.time()))
    -- 得到下一个周一四点的时间戳
    local need_time = os.time({ year = record_date.year, month = record_date.month, day = record_date.day + next_monday, hour = 4, min = 0, sec = 0 })
    --xxmsg("下个周一的时间戳详情")
    --print_r(os.date("*t",need_time))
    -- 判断两个时间戳，如果当前时间戳大于了需要的下一个周一4点的时间戳，就代表需要更新
    if os.time() > need_time then
        return false
    else
        return true
    end
end

--------------------------------------------------------------------------------------
---[读取] 获取ini文件中指定键的值，如果读取该值的时间是在写入时间和下一周一的凌晨4点，如果是就返回值，否则返回空
---@param       section   string     配置文件中节点名称。
---@param       key       string     配置文件中的键名。
---@return                string     返回的值
--------------------------------------------------------------------------------------
function redis.get_user_profile_to_monday(section, key)
    local content = configer.get_user_profile(section, key)
    local parts = utils.split_string(content, ',')
    --xxmsg("记录的时间戳"..tonumber(parts[1]))
    if #parts == 3 and this.is_in_monday_four(tonumber(parts[1])) then
        return parts[3]
    end
    return ''
end


--------------------------------------------------------------------------------
-- 向redis获取指定路径下的数据(json格式)
--
-- @tparam       string     path    路径
-- @tparam       userdata   obj     对象[暂未使用]
-- @treturn      table
-- @usage
-- local table = redis_ent.get_json_redis_by_path('路径', 对象)
--------------------------------------------------------------------------------
redis.get_json_redis_by_path = function(path, obj)
    local ret = {}
    local json_text = main_ctx:redis_get_string(path)
    if obj then
        json_text = '??????????'
    end
    if json_text == 'null' or json_text == '' then
        return {}
    end
    if string.len(json_text) > 0 then
        ret = json_unit.decode(json_text)
    end
    return ret
end


--------------------------------------------------------------------------------
-- 向redis设置指定路径下的数据(string格式)
--
-- @tparam       string     path        路径
-- @tparam       string     session     区块
-- @tparam       string     key         键
-- @tparam       string     value       值
-- @tparam       userdata   obj         对象[暂未使用]
-- @treturn      bool
-- @usage
-- local bool = redis_ent.set_string_redis_ini('路径',区块,键,值)
--------------------------------------------------------------------------------
redis.set_string_redis_ini = function(path, session, key, value)
    local str = main_ctx:redis_get_string(path)
    local session_key = key
    if session ~= nil then
        session_key = session .. ':' .. key
    end
    local ini_obj = ini_unit:new()
    local ret = false
    if ini_obj:parse(str) then
        local r = ini_obj:get_string(session_key)
        if r ~= value then
            ini_obj:set_string(session_key, value)
            local new_string = ini_obj:to_string()
            ret = main_ctx:redis_set_string(path, new_string)
        end
    end
    ini_obj:delete()
    return ret
end


--------------------------------------------------------------------------------
-- 向redis获取指定路径下的数据(string格式)
--
-- @tparam       string     path        路径
-- @tparam       string     session     区块
-- @tparam       string     key         键
-- @tparam       userdata   obj         对象[暂未使用]
-- @treturn      string
-- @usage
-- local str = redis_ent.get_string_redis_ini('路径','区块','键')
--------------------------------------------------------------------------------
redis.get_string_redis_ini = function(path, session, key)
    local str = main_ctx:redis_get_string(path)
    local session_key = key
    if session ~= nil then
        session_key = session .. ':' .. key
    end
    local ini_obj = ini_unit:new()
    local str_r = ''
    if ini_obj:parse(str) then
        str_r = ini_obj:get_string(session_key)
    end
    ini_obj:delete()
    return str_r
end

--------------------------------------------------------------------------------
-- 向redis设置指定路径下的数据(json格式)
--
-- @tparam       string     path    路径
-- @tparam       table      data    写入数据
-- @tparam       userdata   obj     对象[暂未使用]
-- @treturn      table
-- @usage
-- local table = redis_ent.set_json_redis_by_path_and_data('路径',写入数据,对象)
--------------------------------------------------------------------------------
redis.set_json_redis_by_path_and_data = function(path, data)
    if path == nil or path == '' then
        return {}
    end
    local nowRead = main_ctx:redis_get_string(path)
    if data == '' then
        if nowRead ~= 'null' then
            local xx = main_ctx:redis_set_string(path, 'null')
        end
        return {}
    end
    local json_text = json_unit.encode(data)
    if string.len(json_text) > 0 then
        local xx = main_ctx:redis_set_string(path, json_text)
        return xx
    end
    return false
end


return this
